package com.deercrowing.takeaway.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deercrowing.takeaway.common.constant.MessageConstant;
import com.deercrowing.takeaway.common.constant.StatusConstant;
import com.deercrowing.takeaway.common.exception.BusinessException;
import com.deercrowing.takeaway.context.BaseContext;
import com.deercrowing.takeaway.dao.DishesMapper;
import com.deercrowing.takeaway.dao.OrdersMapper;
import com.deercrowing.takeaway.dao.SetmealDishMapper;
import com.deercrowing.takeaway.dao.SetmealsMapper;
import com.deercrowing.takeaway.entity.DishesEntity;
import com.deercrowing.takeaway.entity.SetmealsEntity;
import com.deercrowing.takeaway.service.SetmealsService;
import com.deercrowing.takeaway.vo.DishesItemVO;
import com.deercrowing.takeaway.vo.SetmealDishVO;
import com.deercrowing.takeaway.vo.SetmealsPageVO;
import com.deercrowing.takeaway.vo.SetmealsVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 套餐表(Setmeal)表服务实现类
 *
 * @author guoyongxiang
 * @since 2024-07-11 14:34:12
 */
@Service
@Slf4j
public class SetmealsServiceImpl extends ServiceImpl<SetmealsMapper, SetmealsEntity> implements SetmealsService {

    @Autowired
    SetmealsMapper setmealsMapper;

    @Autowired
    SetmealDishMapper setmealDishMapper;

    @Autowired
    DishesMapper dishesMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Override
    public void compareByContext(SetmealsVO setmealsVO, Integer isAddOrUpdate) {
        Integer id = setmealsVO.getId();
        String name = setmealsVO.getName();

        List<SetmealsEntity> setmealsEntityList = setmealsMapper.selectList();
        if (isAddOrUpdate == 2) {
            for (SetmealsEntity setmealsEntity : setmealsEntityList) {
                if (name.equals(setmealsEntity.getName()) && id != setmealsEntity.getId()) {
                    throw new BusinessException(MessageConstant.DISHNAME_ALREADY_EXISTS);
                }
            }
        }
        else {
            for (SetmealsEntity setmealsEntity : setmealsEntityList) {
                if (name.equals(setmealsEntity.getName())) {
                    throw new BusinessException(MessageConstant.DISHNAME_ALREADY_EXISTS);
                }
            }
        }
    }

    @Override
    public void setmealStatusUpdate(Short status, Integer id) {
        if (ObjectUtils.isEmpty(setmealsMapper.selectById(id))){
            throw new BusinessException(MessageConstant.DISHNAME_ALREADY_EXISTS);
        }

        if (status == StatusConstant.ENABLE) {
            List<DishesEntity> dishesEntityList = dishesMapper.selectListBySetmealId(id);
            if (dishesEntityList != null && dishesEntityList.size() > 0) {
                dishesEntityList.forEach(dish -> {
                    if (StatusConstant.DISABLE == dish.getStatus()) {
                        throw new BusinessException(MessageConstant.SETMEAL_ENABLE_FAILED);
                    }
                });
            }
        }

        setmealsMapper.updateByStatus(status, id);
    }

    @Override
    public IPage<SetmealsVO> serachByCondition(SetmealsPageVO setmealsPageVO) {
        /*
         * Intege和int使用等号的区别
         * 1、Intege包装类获取的是地址(浅拷贝)与目标类相同
         * 2、int获取的是值(浅拷贝)
         */
        int page = setmealsPageVO.getPage() == null ? 1 : setmealsPageVO.getPage();
        int pageSize = setmealsPageVO.getPageSize() == null ? 10 : setmealsPageVO.getPageSize();

        Integer limit = (page - 1) * pageSize;
        setmealsPageVO.setPage(limit);
        setmealsPageVO.setPageSize(pageSize);

        List<SetmealsEntity> setmealsEntityList = setmealsMapper.selectListByCondition(setmealsPageVO);

        if (setmealsEntityList.size() < 0){
            throw new BusinessException(MessageConstant.SETMEAL_NOT_FOUND);
        }

        List<SetmealsVO> setmealsVOList = setmealsEntityList.stream()
                .map(source -> new SetmealsVO(
                        source.getId(),
                        source.getCategoryId(),
                        source.getName(),
                        source.getPrice(),
                        source.getStatus(),
                        source.getImage(),
                        source.getDescription(),
                        source.getUpdateTime(),
                        null,
                        null
                )).collect(Collectors.toList());

        Integer count = setmealsMapper.countSetmealNum(setmealsPageVO);

        IPage<SetmealsVO> entityIPage = new Page<>(page,pageSize);
        entityIPage.setRecords(setmealsVOList);
        entityIPage.setTotal(count);

        return entityIPage;
    }

    @Override
    public SetmealsVO selectById(Long id) {
        SetmealsEntity setmealsEntity = setmealsMapper.selectById(id);
        SetmealsVO setmealsVO = new SetmealsVO();

        BeanUtils.copyProperties(setmealsEntity,setmealsVO);

        List<SetmealDishVO> setmealDishVOList = setmealDishMapper.seletctListBySetmealId(id);// 根据套餐ID搜索出菜品套餐信息

        setmealsVO.setSetmealDishVOList(setmealDishVOList);

        return setmealsVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(List<Long> idList) {
        for (Long id : idList){
            SetmealsEntity setmealsEntity = setmealsMapper.selectById(id);
            if (StatusConstant.ENABLE == setmealsEntity.getStatus()){
                throw new BusinessException(MessageConstant.SETMEAL_ON_SALE);
            }

            setmealsMapper.deleteById(id);
            setmealDishMapper.deleteBySetmealId(id.intValue());
        }
    }

    @Override
    public List<SetmealsVO> selectSetmalWithDish(Short category_id) {
        List<SetmealsEntity> setmealsEntityList = setmealsMapper.selectListByCategory(category_id);
        List<SetmealsVO> setmealsVOList = new ArrayList<>();

        if (setmealsEntityList == null || setmealsEntityList.size() < 0){
            throw new BusinessException(MessageConstant.SETMEAL_NOT_FOUND);
        }

        // 设置单套餐月销量数据
        int countByDishSales = 0;
        YearMonth currentDate = YearMonth.from(LocalDateTime.now());
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("begin",currentDate.atDay(1));
        dataMap.put("end",currentDate.atEndOfMonth());

        for (SetmealsEntity setmealsEntity : setmealsEntityList){
            SetmealsVO setmealsVO = new SetmealsVO();
            BeanUtils.copyProperties(setmealsEntity,setmealsVO);

            dataMap.put("name",setmealsEntity.getName());
            countByDishSales = ordersMapper.sumByDishSales(dataMap) == null ? 0 : ordersMapper.sumByDishSales(dataMap);
            setmealsVO.setSales(countByDishSales);

            List<SetmealDishVO> setmealDishVOList = setmealDishMapper.seletctListBySetmealId(setmealsEntity.getId().longValue());
            setmealsVO.setSetmealDishVOList(setmealDishVOList);
            setmealsVOList.add(setmealsVO);
        }

        return setmealsVOList;
    }

    @Override
    public List<DishesItemVO> selectDishBySetmealId(Integer setmealId) {
        List<DishesItemVO> setmealDishVOList = setmealsMapper.selectDishBySetmealId(setmealId.longValue());

        return setmealDishVOList;
    }

    @Override
    public void updateInfoToDB(Long id, SetmealsVO setmealsVO) {
        SetmealsEntity entity = setmealsMapper.selectById(id);
        if (ObjectUtils.isEmpty(entity))
        {
            throw new BusinessException(MessageConstant.SETMEAL_NOT_FOUND);
        }

        compareByContext(setmealsVO, 2);

        entity.setCategoryId(setmealsVO.getCategoryId())
              .setName(setmealsVO.getName())
              .setPrice(setmealsVO.getPrice())
              .setImage(setmealsVO.getImage())
              .setDescription(setmealsVO.getDescription())
              .setUpdateTime(LocalDateTime.now())
              .setUpdateEmployee(BaseContext.getCurrentId().intValue())
              .updateById();

        //套餐id
        Integer setmealId = entity.getId();

        //2、删除套餐和菜品的关联关系，操作setmeal_dish表，执行delete
        setmealDishMapper.deleteBySetmealId(setmealId);

        List<SetmealDishVO> setmealDishVOList = setmealsVO.getSetmealDishVOList();
        setmealDishVOList.forEach(setmealDish -> {
            setmealDish.setSetmealId(setmealId);
        });
        //3、重新插入套餐和菜品的关联关系，操作setmeal_dish表，执行insert
        setmealDishMapper.insertBatch(setmealDishVOList);
    }

    @Override
    public void insertInfoToDB(SetmealsVO setmealsVO) {
        SetmealsEntity entity = new SetmealsEntity();

        BeanUtils.copyProperties(setmealsVO,entity);

        compareByContext(setmealsVO, 1);

        entity.setId(0)
              .setStatus(StatusConstant.DISABLE)
              .setCreateTime(LocalDateTime.now())
              .setUpdateTime(LocalDateTime.now())
              .setCreateEmployee(BaseContext.getCurrentId().intValue())
              .setUpdateEmployee(BaseContext.getCurrentId().intValue())
              .insert();

        Integer setmeal_Id = setmealsMapper.selectBySetmealId(entity.getName());

        List<SetmealDishVO> setmealDishVOList = setmealsVO.getSetmealDishVOList();
        if (setmealDishVOList != null && setmealDishVOList.size() > 0) {
            setmealDishVOList.forEach(setmealDish -> {
                setmealDish.setSetmealId(setmeal_Id);
            });
            //向口味表插入n条数据
            setmealDishMapper.insertBatch(setmealDishVOList);
        }
    }
}

